/*
 * Copyright (c) 2007 Easter.
 * 
 * Author: Yichao Zhang
 * 
 * Email: Yichao.Zhang@gmail.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.easter.blogsync;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gdata.data.Entry;
import com.google.gdata.data.Person;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.TextContent;

public class BloggerWebService {

  public boolean createComment(String blogID, String postID, Entry entry)
      throws IOException {
    List<Person> persons = entry.getAuthors();
    if (null == persons) {
      String error = "No author in the entry";
      BlogHelper.logError(error);
      throw new NullPointerException(error);
    }
    // comment should have only one author
    Person person = persons.get(0);
    String author = person.getName();
    author = (null == author) ? "" : author;
    String authorURL = person.getUri();
    authorURL = (null == authorURL) ? "" : authorURL;
    TextContent tc = (TextContent) entry.getContent();
    String comment = tc.getContent().getPlainText();
    return createComment(blogID, postID, author, authorURL, comment);
  }

  private boolean createComment(String blogID, String postID, String author,
      String authorURL, String comment) throws IOException {
    // 1 retrieve securityToken and cookies
    String url = "https://www.blogger.com/comment.g";
    url += "?blogID=" + blogID + "&postID=" + postID;
    HttpURLConnection huc = (HttpURLConnection) new URL(url).openConnection();
    huc.setInstanceFollowRedirects(false);
    huc.setRequestProperty("User-Agent", "Blogsync-java;Zeaster");
    huc.setDoOutput(true);
    String response = getResponseAsString(huc);
    if (HttpURLConnection.HTTP_OK != huc.getResponseCode()) {
      String msg = "retrieve securityToken and cookies fails\n";
      msg += response + "\n";
      throw new IOException(msg);
    }
    String securityToken = extractSecurityTokenFromResponse(response);
    String cookies = huc.getHeaderField("Set-Cookie");

    // 2 post comment
    url = "https://www.blogger.com/comment.do";
    huc = (HttpURLConnection) new URL(url).openConnection();
    huc.setInstanceFollowRedirects(false);
    huc.setRequestMethod("POST");
    huc.setRequestProperty("User-Agent", "Blogsync-java;Zeaster");
    huc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    huc.setRequestProperty("Cookie", cookies);
    huc.setDoOutput(true);
    Map<String, String> params = new HashMap<String, String>();
    params.put("blogID", blogID);
    params.put("postID", postID);
    params.put("securityToken", securityToken);
    params.put("iden", "Other");
    params.put("postBody", comment);
    params.put("anonName", author);
    params.put("anonURL", authorURL);
    addParamsAndExecuteMethord(params, huc);
    if (HttpURLConnection.HTTP_MOVED_TEMP == huc.getResponseCode()) {
      return true;
    } else {
      String msg = "post comment fails\n";
      msg += getResponseAsString(huc) + "\n";
      throw new IOException(msg);
    }
  }

  private void addParamsAndExecuteMethord(Map<String, String> params,
      HttpURLConnection huc) throws IOException {
    DataOutputStream printout = new DataOutputStream(huc.getOutputStream());
    StringBuffer sb = new StringBuffer();
    for (String key : params.keySet()) {
      sb.append("&");
      sb.append(key);
      sb.append("=");
      String value = params.get(key);
      value = URLEncoder.encode(value, "utf-8");
      sb.append(value);
    }
    printout.writeBytes(sb.toString());
    printout.flush();
    printout.close();
  }

  private String extractSecurityTokenFromResponse(String response) {
    String token = "name=\"securityToken\" value=\"";
    int start = response.indexOf(token) + token.length();
    int end = response.indexOf("\"", start);
    return response.substring(start, end);
  }

  private String getResponseAsString(HttpURLConnection huc) throws IOException {
    InputStreamReader isr = new InputStreamReader(huc.getInputStream());
    BufferedReader in = new BufferedReader(isr);
    String input = null;
    StringBuffer response = new StringBuffer(1024);
    while ((input = in.readLine()) != null) {
      response.append(input);
    }
    return response.toString();
  }

  // for test
  public static void main(String[] args) {
    BloggerWebService bg = new BloggerWebService();
    try {
      Entry entry = new Entry();
      Person p = new Person("Zeaster");
      p.setUri("http://zeaster.blogspot.com");
      entry.setContent(new PlainTextConstruct("����\npost from java client"));
      entry.getAuthors().add(p);
      boolean f = bg.createComment("18083698", "376116388691735433", entry);
      System.out.println(f);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
